<?php
declare(strict_types=1);

namespace App\Controller\Admin\V1\PointPosition;

use App\Controller\Admin\AdminController;
use App\Helper\Utils;
use App\Job\PaperListStaticExportJob;
use App\Model\ExportFile;
use App\Model\PointPosition;
use App\Model\PointPositionCategory;
use App\Model\PositionSupervise;
use App\Model\PositionSuperviseSheet;
use App\Repositories\AreaRepository;
use App\Repositories\CompanyUnitRepository;
use App\Repositories\PointPositionCategoryRepository;
use App\Repositories\PointPositionRepository;
use App\Repositories\PositionPaperRepository;
use App\Repositories\PositionSuperviseRepository;
use App\Repositories\PositionSuperviseSheetRepository;
use App\Repositories\SuperviseSheetAssignRepository;
use App\Repositories\SuperviseSheetReplyRepository;
use App\Repositories\UserRepository;
use App\Request\StorePositionPaperRequest;
use App\Services\PositionSuperviseService;
use App\Services\QueueService;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;

class PaperController extends AdminController
{
    /**
     * @Inject
     * @var PositionSuperviseService
     */
    public $supervise_service;

    /**
     * @Inject
     * @var QueueService
     */

    public $queue_service;

    /**
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function all()
    {
        $position_id = $this->request->input('position_id',0);
        $category_id = $this->request->input('category_id',0);
        if(!$category_id){
            return $this->response->error(10014,'请输入分类id');
        }
        $where=[
            'category_id' => [
                'field' => 'category_id',
                'value' => $category_id
            ]
        ];
        if($position_id){
            $where['position_id']=[
                'field' => 'position_id',
                'value' => $position_id
            ];
        }
        $return= PositionPaperRepository::getInstance()->all('*',$where,[[
            'field' => 'listorder',
            'sort' => 'asc'
        ]]);
        return $this->response->success($return);
    }

    public function store(StorePositionPaperRequest $request){
        $params = $request->all();
        $paper = $params['paper'];
        if(!count($paper)){
            return $this->response->error(10040,'请上传题目');
        }
        $all_score=0;
        foreach($paper as $key=>$item){
            $insert_data = $item;
            $all_score+=$item['score'];
            $insert_data['id'] = $item['id']>0?$item['id']:0;
            $insert_data['position_id'] = $params['position_id'];
            $insert_data['category_id'] = $params['category_id'];
            $insert_data['listorder'] = $key;
            $result = PositionPaperRepository::getInstance()->store($insert_data);
        }
        if($params['category_id']){
            $category = PointPositionCategoryRepository::getInstance()->getById($params['category_id']);
            $category->full_score = $all_score;
            $category->save();
        }
        return $this->response->success([
            'position_id' => $params['position_id']
        ]);
    }

    public function delete(){
        $id = $this->request->input('id');
        $result =PositionPaperRepository::getInstance()->delete($id);
        if($result){
            return $this->response->success($result['data']);
        }
        return $this->response->error(10000,$result['msg']);
    }

    public function answerConsts(){
        $status = PositionSupervise::getLabels('status');
        $return=[];
        $return['status'] = [];
        foreach ($status as $key=>$val){
            $obj=[
                'name' => $val,
                'value' => $key
            ];
            $return['status']=array_merge($return['status'],[$obj]);
        }
        return $this->response->success($return);
    }

    public function answers(){
        $admin = $this->request->getAttribute('admin');
        $unit_id = $admin->unit_id;
        $rows = $this->request->input('rows',10);
        $mobile = $this->request->input('mobile','');
        $position_name = $this->request->input('position_name','');
        $district_id = $this->request->input('district_id','all');
        $category_id = $this->request->input('category_id','all');
        $status = $this->request->input('status','all');
        $start_time = $this->request->input('start_time','');
        $end_time = $this->request->input('end_time','');
        $search=[];
        $join=[];
        $orderBy= [
            [
                'field' => 'position_supervise.id',
                'sort' => 'desc'
            ]
        ];
        $join['point_position']=[
            'on' => ['position_supervise.position_id','=','point_position.id'],
            'where'=>[]
        ];
        $join_point_position_where=[];
        if($district_id!='all'){
            $join_point_position_where['district_id']=[
                'field' => 'district_id',
                'value' => $district_id
            ];
        }
        if($category_id!='all'){
            $join_point_position_where['category_id']=[
                'field' => 'category_id',
                'value' => $category_id
            ];
        }
        if($position_name!=''){
            $join_point_position_where['name']=[
                'field' => 'name',
                'value' => $position_name,
                'method' => 'like'
            ];
        }
        $join['point_position']['where']=$join_point_position_where;
        if($status!='all'){
            if($status==1){
//                $search['status'] = [
//                    'field' => 'status',
//                    'value' => PositionSupervise::STATUS_DONE,
//                    'method'=>'<'
//                ];
                $search['is_grade'] = [
                    'field' => 'is_grade',
                    'value' => 0,
                ];
            }elseif($status==2){
//                $search['status'] = [
//                    'field' => 'status',
//                    'value' => PositionSupervise::STATUS_DONE
//                ];
                $search['is_grade'] = [
                    'field' => 'is_grade',
                    'value' => 1,
                ];
            }

        }
        if($start_time!=''&&$end_time!=''){
            $search['created_at_start']=[
                'field' => 'position_supervise.created_at',
                'value' => $start_time,
                'method'=>'>='
            ];
            $search['created_at_end']=[
                'field' => 'position_supervise.created_at',
                'value' => $end_time,
                'method'=>'<='
            ];
        }
        if($unit_id){
            $join['position_units']=[
                    'on' => ['position_units.position_id','=','point_position.id'],
                    'where'=>[[
                        'field' => 'position_units.unit_id',
                        'value' => $unit_id,
                    ],[
                        'field' => 'position_units.deleted_at',
                        'value'=>'',
                        'method'=>'null'
                    ]]
                ];
        }
        if($mobile!=''){
            $join['users']=[
                'on' => ['position_supervise.user_id','=','users.id'],
                'where'=>[[
                    'field' => 'mobile',
                    'value' => $mobile,
                    'method' => 'like'
                ]]
            ];
        }
        $datas = PositionSuperviseRepository::getInstance()->getList(['position_supervise.*'],$search,['limit'=>$rows],$orderBy,$join,['position']);
        if($datas['result']){
            foreach ($datas['result'] as &$item){
                $item['user'] = UserRepository::getInstance()->getBaseInfo($item['user_id']);
                if($unit_id){
                    $item['user']->mobile = Utils::replacePhone($item['user']->mobile);
                    $item['user']->avatar = config('common.image_prefix').'/images/avatar.jpg';
                    if($item['user']->wechat){
                        $item['user']->wechat->wx_nickname='创嘟嘟用户';
                        $item['user']->wechat->wx_avatar=config('common.image_prefix').'/images/avatar.jpg';
                    }
                }
                if(isset($item['position'])&&!empty($item['position'])){
                    $item['position']['district'] = AreaRepository::getInstance()->getById($item['position']['district_id']);
                }
            }
        }
        return $this->response->success($datas);
    }

    public function answerDetail(){
        $id = $this->request->input('id',0);
        $supervise = PositionSuperviseRepository::getInstance()->getById($id);
        $position_info = PointPositionRepository::getInstance()->one(['id','name','category_id','district_id'],[[
            'field' => 'id',
            'value' => $supervise->position_id
        ]]);
        $category_info=[];
        $district_info=[];
        if($position_info){
            $category_info = PointPositionCategoryRepository::getInstance()->one(['id','name'],[[
                'field' => 'id',
                'value' => $position_info->category_id
            ]]);
            $district_info = AreaRepository::getInstance()->one(['id','name'],[[
                'field' => 'id',
                'value' => $position_info->district_id
            ]]);
        }
        $supervise->position = $position_info;
        $supervise->category = $category_info;
        $supervise->district = $district_info;
        $questions = PositionSuperviseSheetRepository::getInstance()->all('*',[[
            'field' => 'supervise_id',
            'value' => $id
        ]]);
        foreach ($questions as &$question){
            $max_score_result = PositionPaperRepository::getInstance()->one(['score'],[[
                'field' => 'id',
                'value' => $question->paper_id
            ]]);
            $question->max_score = object_get($max_score_result,'score',0);
            if($question->extend_images){
                $images = explode(',',$question->extend_images);
                $images = collect($images)->map(function($image){
                    preg_match("/(?:[http|https]:\/\/)([^\/]+)/", $image, $matched);
                    if(empty($matched)){
                        return  env('QINBIU_DOMAIN').$image;
                    }
                    return $image;
                });
                $question['extend_images'] = $images;
            }
            if($question->reply_images){
                $images = explode(',',$question->reply_images);
                $images=collect($images)->map(function($image){
                    preg_match("/(?:[http|https]:\/\/)([^\/]+)/", $image, $matched);
                    if(empty($matched)){
                        return  env('QINBIU_DOMAIN').$image;
                    }
                    return $image;
                });
                $question['reply_images'] = $images;
            }
        }
        return $this->response->success([
            'supervise' => $supervise,
            'list' => $questions
        ]);
    }

    public function answerDelete(){
        $id = $this->request->input('id',0);
        $result = PositionSuperviseRepository::getInstance()->delete($id);
        PositionSuperviseSheetRepository::getInstance()->deleteAll([[
            'field' => 'supervise_id',
            'value' => $id
        ]]);
        return $this->response->success([]);
    }

    public function answerReply(){
        $admin = $this->request->getAttribute('admin');
        $id = $this->request->input('id',0);
        $image = $this->request->input('image','');
        $reply_txt = $this->request->input('reply_txt','');
        $image_arr = explode(',',$image);
        foreach($image_arr as &$item){
            $item=str_replace(env('QINBIU_DOMAIN'),'',$item);
        }
        $answer = PositionSuperviseSheetRepository::getInstance()->getById($id);
        //查询未答复的数量
        $count = PositionSuperviseSheet::query()->where('supervise_id',$answer->supervise_id)
            ->where('answer_txt','不符合')
            ->whereNull('reply_images')
            ->where('id','!=',$id)
            ->count('id');
        DB::beginTransaction();
        try{
            $answer->reply_images = implode(',',$image_arr);
            $answer->reply_txt = $reply_txt;
            $answer->admin_id = $admin->id;
            if(!$answer->save()){
                throw new \Exception('更新回复内容失败');
            }
            $supervise = PositionSuperviseRepository::getInstance()->getById($answer->supervise_id);
            if(!$count){
                $supervise->status = PositionSupervise::STATUS_DONE;
            }else{
                $supervise->status = PositionSupervise::STATUS_REPLY;
            }
            if(!$supervise->save()){
                throw new \Exception('更新状态失败');
            }
            DB::commit();
        }catch(\Throwable $e){
            DB::rollBack();
            return $this->response->error(11414,$e->getMessage());
        }
        return $this->response->success([]);
    }

    public function sheet(){
        $admin = $this->request->getAttribute('admin');
        $menu = $this->request->input('menu',1);
        $mobile = $this->request->input('mobile','');
        $district_id = $this->request->input('district_id','all');
        $category_id = $this->request->input('category_id','all');
        $start_time = $this->request->input('start_time','');
        $end_time = $this->request->input('end_time','');
        $categories = PointPositionCategoryRepository::getInstance()->all(['id','name']);
        $categories = $categories->keyBy('id');
        $districts = AreaRepository::getInstance()->all(['id','name'],[[
            'field' => 'parent_id',
            'value' =>223
        ]]);
        $districts = $districts->keyBy('id');
        $search=[
//            'score' =>[
//                'field' => 'score',
//                'value' => '0'
//            ]
        ];
        $unit_id = $admin->unit_id;
        $unit = CompanyUnitRepository::getInstance()->getById($unit_id);

        $rows = $this->request->input('rows',10);
        $orderBy=[[
            'field' => 'position_supervise_sheet.id',
            'sort' => 'desc'
        ]];
        $join['position_supervise']=[
            'on' => ['position_supervise_sheet.supervise_id','=','position_supervise.id'],
            'where'=>[[
                'field' => 'position_supervise.deleted_at',
                'value' => null,
                'method' => 'null'
            ]]
        ];
//        if($unit&&$unit->parent_id){
//            $search['unit_id']=[
//                'field' => 'unit_id',
//                'value' => $unit_id
//            ];
//        }elseif($unit&&!$unit->parent_id){
//            $join['point_position']=[
//                'on' => ['position_supervise.position_id','=','point_position.id'],
//                'where'=>[[
//                    'field' => 'point_position.deleted_at',
//                    'value' => null,
//                    'method' => 'null'
//                ],[
//                    'field' => 'main_unit_id',
//                    'value' => $unit_id
//                ]]
//            ];
//        }
        if($start_time!=''&&$end_time!=''){
            $search['created_at_start']=[
                'field' => 'position_supervise_sheet.created_at',
                'value' => $start_time,
                'method'=>'>='
            ];
            $search['created_at_end']=[
                'field' => 'position_supervise_sheet.created_at',
                'value' => $end_time,
                'method'=>'<='
            ];
        }
        if($mobile!=''){
            $join['users']=[
                'on' => ['position_supervise.user_id','=','users.id'],
                'where'=>[[
                    'field' => 'mobile',
                    'value' => $mobile,
                    'method' => 'like'
                ]]
            ];
        }
        $join['point_position']=[
            'on' => ['position_supervise.position_id','=','point_position.id'],
            'where'=>[]
        ];
        $join_point_position_where=[];
        if($district_id!='all'){
            $join_point_position_where['district_id']=[
                'field' => 'district_id',
                'value' => $district_id
            ];
        }
        if($category_id!='all'){
            $join_point_position_where['category_id']=[
                'field' => 'category_id',
                'value' => $category_id
            ];
        }
        $join['point_position']['where']=$join_point_position_where;
        switch ($menu){
            case 1://待答复
                $search['sheet_status']=[
                    'field' => 'sheet_status',
                    'value' => $unit_id&&$admin->parent_id?PositionSuperviseSheet::SHEET_STATUS_ASSIGN:PositionSuperviseSheet::SHEET_STATUS_DEFAULT
                ];
                break;
            case 2://已分派
                $search['sheet_status']=[
                    'field' => 'sheet_status',
                    'value' => PositionSuperviseSheet::SHEET_STATUS_ASSIGN
                ];
                break;
            case 3://已退回
                $search['sheet_status']=[
                    'field' => 'sheet_status',
                    'value' => PositionSuperviseSheet::SHEET_STATUS_REJECT
                ];
                break;
            case 4://已答复
                $search['sheet_status']=[
                    'field' => 'sheet_status',
                    'value' => PositionSuperviseSheet::SHEET_STATUS_REPLY
                ];
                break;
            case 5://已评分
                $search['sheet_status']=[
                    'field' => 'sheet_status',
                    'value' => PositionSuperviseSheet::SHEET_STATUS_SCORE
                ];
                break;
            case 6://未评分
                $search['sheet_status']=[
                    'field' => 'sheet_status',
                    'value' => PositionSuperviseSheet::SHEET_STATUS_SCORE,
                    'method' => '<'
                ];
                break;
        }
        $columns =[
            'position_supervise_sheet.*',
            'position_id',
            'user_id'
        ];
        $datas = PositionSuperviseSheetRepository::getInstance()->getList($columns,$search,['limit'=>$rows],$orderBy,$join);
        if(!empty($datas['result'])){
            foreach ($datas['result'] as &$item){
                if($item['extend_images']){
                    $images = explode(',',$item['extend_images']);
                    $images = collect($images)->map(function($image){
                        preg_match("/(?:[http|https]:\/\/)([^\/]+)/", $image, $matched);
                        if(empty($matched)){
                            return  env('QINBIU_DOMAIN').$image;
                        }
                        return $image;
                    });
                    $item['extend_images'] = $images->toArray();
                }else{
                    $item['extend_images']=[];
                }
                if($item['reply_images']){
                    $images = explode(',',$item['reply_images']);
                    $images = collect($images)->map(function($image){
                        preg_match("/(?:[http|https]:\/\/)([^\/]+)/", $image, $matched);
                        if(empty($matched)){
                            return  env('QINBIU_DOMAIN').$image;
                        }
                        return $image;
                    });
                    $item['reply_images'] = $images->toArray();
                }else{
                    $item['reply_images']=[];
                }
                $item['user'] = UserRepository::getInstance()->getBaseInfo($item['user_id']);
                if($unit_id){
                    $item['user']->mobile = Utils::replacePhone($item['user']->mobile);
                    $item['user']->avatar = config('common.image_prefix').'/images/avatar.jpg';
                    if($item['user']->wechat){
                        $item['user']->wechat->wx_nickname='创嘟嘟用户';
                        $item['user']->wechat->wx_avatar=config('common.image_prefix').'/images/avatar.jpg';
                    }
                }
                $item['position'] = PointPosition::query()->where('id',$item['position_id'])->withTrashed()->first();
                $item['category'] = isset($categories[$item['position']->category_id])?$categories[$item['position']->category_id]:null;
                $item['district'] = isset($districts[$item['position']->district_id])?$districts[$item['position']->district_id]:null;
                $item['last_reply'] = SuperviseSheetReplyRepository::getInstance()->one('*',[[
                    'field' => 'sheet_id',
                    'value' => $item['id']
                ]],[[
                    'field' => 'id',
                    'sort' => 'desc'
                ]]);
                $item['assign'] = SuperviseSheetAssignRepository::getInstance()->one('*',[[
                    'field'=>'sheet_id',
                    'value' => $item['id']
                ]],[[
                    'field' => 'id',
                    'sort' => 'desc'
                ]]);
                if($item['assign']){
                    $assign_unit = CompanyUnitRepository::getInstance()->getById($item['assign']->unit_id);
                    $item['assign']->unit_name = object_get($assign_unit,'name','');
                }else{
                    $item['assign']['unit_name']='';
                }
            }
        }
        return $this->response->success($datas);
    }

    public function sheetAssign(){
        $params = $this->request->all();
        $admin = $this->request->getAttribute('admin');
        $result = $this->supervise_service->sheetAssign($params,$admin,'admin');
        if($result['success']){
            return $this->response->success([]);
        }
        return $this->response->error(10050,$result['msg']);
    }

    public function sheetReject(){
        $params = $this->request->all();
        $admin = $this->request->getAttribute('admin');
        $result = $this->supervise_service->sheetReject($params,$admin,'admin');
        if($result['success']){
            return $this->response->success([]);
        }
        return $this->response->error(10050,$result['msg']);
    }

    public function sheetReply(){
        $params = $this->request->all();
        $admin = $this->request->getAttribute('admin');
        $result = $this->supervise_service->sheetReply($params,$admin,'admin');
        if($result['success']){
            return $this->response->success([]);
        }
        return $this->response->error(10050,$result['msg']);
    }

    public function sheetScore(){
        $params = $this->request->all();
        $admin = $this->request->getAttribute('admin');
        $result = $this->supervise_service->sheetScore($params,$admin,'admin');
        if($result['success']){
            return $this->response->success([]);
        }
        return $this->response->error(10050,$result['msg']);
    }


    public function answersStatic(){
        $admin = $this->request->getAttribute('admin');
        $unit_id = $admin->unit_id;
        $rows = $this->request->input('rows',10);
        $district_id = $this->request->input('district_id','all');
        $category_id = $this->request->input('category_id','all');
        $status = $this->request->input('status','all');
        $start_time = $this->request->input('start_time','');
        $end_time = $this->request->input('end_time','');
        $search=[];
        $join=[];
        $orderBy= [
            [
                'field' => 'allscore',
                'sort' => 'desc'
            ],
            [
                'field' => 'position_id',
                'sort' => 'asc'
            ]
        ];
        $categories = PointPositionCategory::query()->withTrashed()->get()->keyBy('id');
        $join['point_position']=[
            'on' => ['position_supervise.position_id','=','point_position.id'],
            'where'=>[]
        ];
        $join_point_position_where=[
            'deleted_at'=>[
                'field' => 'point_position.deleted_at',
                'value'=>'',
                'method'=>'null'
            ]
        ];
        if($district_id!='all'){
            $join_point_position_where['district_id']=[
                'field' => 'district_id',
                'value' => $district_id
            ];
        }
        if($category_id!='all'){
            $join_point_position_where['category_id']=[
                'field' => 'category_id',
                'value' => $category_id
            ];
        }
        $join['point_position']['where']=$join_point_position_where;
        if($status!='all'){
            $search['status'] = [
                'field' => 'status',
                'value' => $status
            ];
        }
        if($start_time!=''&&$end_time!=''){
            $search['created_at_start']=[
                'field' => 'position_supervise.created_at',
                'value' => $start_time,
                'method'=>'>='
            ];
            $search['created_at_end']=[
                'field' => 'position_supervise.created_at',
                'value' => $end_time,
                'method'=>'<='
            ];
        }
        if($unit_id){
            $join['position_units']=[
                'on' => ['position_units.position_id','=','point_position.id'],
                'where'=>[[
                    'field' => 'position_units.unit_id',
                    'value' => $unit_id,
                ],[
                    'field' => 'position_units.deleted_at',
                    'value'=>'',
                    'method'=>'null'
                ]]
            ];
        }
        $datas = PositionSuperviseRepository::getInstance()->getList(['position_supervise.*'],$search,['limit'=>$rows],$orderBy,$join,['position']);
        if($datas['result']){
            foreach ($datas['result'] as &$item){
                $item['category_name'] = $categories[$item['position']['category_id']]->name;
                $item['user'] = UserRepository::getInstance()->getBaseInfo($item['user_id']);
                if(isset($item['position'])&&!empty($item['position'])){
                    $item['position']['district'] = AreaRepository::getInstance()->getById($item['position']['district_id']);
                }
                $item['zero_num'] = PositionSuperviseSheet::query()->where('supervise_id',$item['id'])->where('score',0)->count('id');
                $item['wait_reply_num'] = PositionSuperviseSheet::query()->where('supervise_id',$item['id'])->where('score',0)
                    ->where('sheet_status',PositionSuperviseSheet::SHEET_STATUS_DEFAULT)->count('id');
                $item['reply_num'] = PositionSuperviseSheet::query()->where('supervise_id',$item['id'])->where('score',0)
                    ->where('sheet_status',PositionSuperviseSheet::SHEET_STATUS_REPLY)->count('id');
            }
        }
        return $this->response->success($datas);
    }

    public function answersStaticExport(){
        $admin = $this->request->getAttribute('admin');
        $params = $this->request->all();
        $unit_id = $admin->unit_id;
        $params['unit_id'] = $unit_id;
        $hash_id = $params['hash_id'];
        $exists = ExportFile::query()->where('hash_id',$hash_id)->first();
        if(!$exists){
            $newname = Utils::createFileName().'.csv';
            $dir = '/uploads/export/'.date('Ym').'/'.date('d').'/';
            $folder = BASE_PATH.'/public'.$dir;
            if (!is_dir($folder)) {
                mkdir($folder, 0777, true);
            }
            $model = new ExportFile();
            $model->hash_id=$hash_id;
            $model->file_url = $dir.$newname;
            $model->type = 'thread';
            $model->params = json_encode($params);
            if(!$model->save()){
                return $this->response->error(10050,'创建导出失败');
            }
            $params['file_url'] = $dir.$newname;
            cache()->set('export_'.$hash_id,0);
            $this->queue_service->push(new PaperListStaticExportJob($params));
            return $this->response->success([
                'hash_id' => $hash_id,
                'progress' => 0,
                'file_url' => config('common.image_prefix').$dir.$newname
            ]);
        }
        return $this->response->success([
            'hash_id' => $hash_id,
            'progress' => cache()->get('export_'.$hash_id),
            'file_url' => config('common.image_prefix').$exists->file_url
        ]);
    }

    public function grade(){
        $params = $this->request->all();
        $admin = $this->request->getAttribute('admin');
        $result = $this->supervise_service->grade($params,$admin,'admin');
        if($result['success']){
            return $this->response->success([]);
        }
        return $this->response->error(10050,$result['msg']);
    }

}